package it.eng.area118.mdocommon.binding;

import java.lang.reflect.Field;

import android.app.Activity;
import android.text.Editable;
import android.text.method.BaseKeyListener;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

/**
 * Classe che si preoccupa di legare un Bean con una View.
 * 
 * TODO: Realizzare unbind.
 * 
 * @author Mauro Miranda
 * 
 */
public class BeanViewBinder {

	protected static BeanViewBinder instance;

	protected BeanViewBinder() {
	}

	public static BeanViewBinder getInstance() {
		if (instance == null) {
			instance = new BeanViewBinder();
		}
		return instance;
	}

	/**
	 * Lega un Bean java (POJO), opportunamente annotato, alla view. Tutti i valori contenenti nel bean verranno
	 * caricati nei componenti grafici. Ogni modifica sul componente grafico si ripercuote sui dati presenti nel Bean.
	 * 
	 * @param o
	 * @param view
	 */
	public void bind(Object o, Activity view) {
		Field[] fields = o.getClass().getDeclaredFields();
		// per ogni campo del bean
		for (Field field : fields) {
			// carico l'annotation del Field
			ViewBind annotations = field.getAnnotation(ViewBind.class);
			if (annotations != null) {
				// carico l'id del componente grafico
				int id = annotations.id();
				// carico il componente grafico dall'id
				View child = view.findViewById(id);
				// rendo il campo accessibile
				field.setAccessible(true);
				try {
					Object value = field.get(o);
					// assegno il valore del campo al componente grafico
					setValueToField(value, child);
					// TODO: aggiungere i listener
					addListenerToView(o, child, field);

				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	
	
	public void bind(Object o, View view) {
		Field[] fields = o.getClass().getDeclaredFields();
		// per ogni campo del bean
		for (Field field : fields) {
			// carico l'annotation del Field
			ViewBind annotations = field.getAnnotation(ViewBind.class);
			if (annotations != null) {
				// carico l'id del componente grafico
				int id = annotations.id();
				// carico il componente grafico dall'id
				View child = view.findViewById(id);
				// rendo il campo accessibile
				field.setAccessible(true);
				try {
					Object value = field.get(o);
					// assegno il valore del campo al componente grafico
					setValueToField(value, child);
					// TODO: aggiungere i listener
					addListenerToView(o, child, field);

				} catch (IllegalArgumentException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	protected void setValueToField(Object value, View field) {
		if (value == null) {
			value = " ";
		}
		if (field instanceof TextView) {
			((TextView) field).setText(value.toString());
		}
	}

	protected void addListenerToView(final Object o, final View viewField, final Field field) {
		if (viewField instanceof EditText) {
			((EditText) viewField).setKeyListener(new BaseKeyListener() {
				@Override
				public boolean onKeyUp(View arg0, Editable arg1, int arg2, KeyEvent arg3) {
					// TODO Auto-generated method stub
					String value = ((EditText) viewField).getText().toString();
					try {
						field.set(o, value);
					} catch (Exception e) {
						e.printStackTrace();
					} 
					return true;
				}

				@Override
				public int getInputType() {
					// TODO Auto-generated method stub
					return 0;
				}
			});
		}
	}
}
